; diskmenu.asm
; disk menu 

	.include "common.inc"
	.include "global.inc"
	.include "string.inc"
	.include "disk.inc"
	.include "msgbox.inc"
	.include "window.inc"
	.include "screen.inc"
	.include "wutil.inc"
	.include "execfun.inc"
	.include "listbox.inc"
	.include "cursor.inc"
	.include "text.inc"
	.include "files.inc"
	.include "memory.inc"
	.include "util.inc"
	.include "petscii.inc"
	.include "dmgui.inc"
	.include "mouse.inc"
	.include "winsys.inc"

	.import wait_yield

	.export menu_init
	
	MAX_NAME_LEN = 16
	MAX_TYPE_LEN = 3
	
	.struct DirEntry
		size	.word
		type	.res 4 ; MAX_TYPE_LEN+1
		name	.res 17 ; MAX_NAME_LEN+1
	.endstruct
	
	INIT_LIST_SIZE = 10
	
	dreg = reg0

	.segment "RODATA"
	
msgtitle:	.byte 6, "Drives"

drive8:		.byte $AA, $55, $7F, $80, $81, $9F, $81, $80
			.byte $7F, $50, $A9, $52, $A9, $52, $A9, $50
			.byte $AA, $55, $FE, $01, $81, $F9, $81, $01
			.byte $FE, $15, $8A, $55, $8A, $55, $8A, $15
bm_drive8:	.byte 16, 16
			.word drive8
tx_drive8:	.byte $FF
			.word bm_drive8

drive9:		.byte $AA, $55, $7F, $80, $81, $9F, $81, $80
			.byte $7F, $50, $A9, $52, $A9, $50, $AB, $50	
			.byte $AA, $55, $FE, $01, $81, $F9, $81, $01
			.byte $FE, $15, $8A, $55, $CA, $55, $8A, $15
bm_drive9:	.byte 16, 16
			.word drive9
tx_drive9:	.byte $FF
			.word bm_drive9

drive10:	.byte $AA, $55, $7F, $80, $81, $9F, $81, $80
			.byte $7F, $50, $A2, $56, $A2, $52, $A2, $50
			.byte $AA, $55, $FE, $01, $81, $F9, $81, $01
			.byte $FE, $05, $4A, $A5, $AA, $A5, $4A, $05
bm_drive10:	.byte 16, 16
			.word drive10
tx_drive10:	.byte $FF
			.word bm_drive10

drive11:	.byte $AA, $55, $7F, $80, $81, $9F, $81, $80
			.byte $7F, $50, $A2, $56, $A2, $52, $A2, $50
			.byte $AA, $55, $FE, $01, $81, $F9, $81, $01
			.byte $FE, $15, $4A, $D5, $4A, $55, $4A, $15
bm_drive11:	.byte 16, 16
			.word drive11
tx_drive11:	.byte $FF
			.word bm_drive11

drvlo:		.byte <tx_drive8, <tx_drive9, <tx_drive10, <tx_drive11
drvhi:		.byte >tx_drive8, >tx_drive9, >tx_drive10, >tx_drive11

txoutmem:	.byte 18, "Not enough memory!"

tx_open:	.byte 4, $4F, $10, $05, $0E
tx_cmd:		.byte 1, 0

	.segment "DATA"
	
ptrlo:		.byte 0
ptrhi:		.byte 0

drvactive:	.byte 0, 0, 0, 0
drvlistbox:	.byte 0, 0, 0, 0
dirlistlo:	.byte 0, 0, 0, 0
dirlisthi:  .byte 0, 0, 0, 0
dirlistsz:	.byte 0, 0, 0, 0
dirlistlen:	.byte 0, 0, 0, 0

	.segment "CODE"

;
;	init drive menu (scan drives, show result, ...)
;

menu_init:	jsr scndrvi
			jsr init_gui
			jsr startmsg
			rts

startmsg:	lda #250				; init msg buf
			sta scratchbuf1
			lda #<scratchbuf1
			ldx #>scratchbuf1
			jsr ssetbuf
			jsr sclear				; add title
			lda #<msgtitle
			ldx #>msgtitle
			jsr saddstr
			jsr drvfirst			; enum drives
@nextdrv:	cmp #8
			bcc @drvcmpl
			stx ptrlo
			sty ptrhi
			pha
			lda #13
			jsr saddch
			pla
			ldx #0
			jsr sputuint
			lda #':'
			jsr saddch
			lda #'"'
			jsr saddch
			lda ptrlo
			ldx ptrhi
			jsr saddstr
			lda #'"'
			jsr saddch
			jsr drvnext
			jmp @nextdrv
@drvcmpl:	lda #<(scratchbuf1+1)	; open message box 
			ldx #>(scratchbuf1+1)
			ldy #MSG_INFO
			jsr message
			rts

	.segment "DATA"
	
curposx:	.byte 0
curposy:	.byte 0
curfrm:		.byte 0
curwin:		.byte 0
curdrv:		.byte 0
curbox:		.byte 0

	INITX = 8
	INITY = 16
	SIZEX = 16
	SIZEY = 16
	ADVX  = 24
	
	.segment "CODE"

;
;	Scan drives & create icons
;

scndrvi:	lda #INITX
			sta curposx
			lda #INITY
			sta curposy
			jsr drvfirst			; enum drives
@nextdrv:	cmp #8
			bcc @drvcmpl
			jsr crtdrvi
			jsr drvnext
			jmp @nextdrv
@drvcmpl:	rts

;
;	Create drive icon (A .. drive no.)
;

crtdrvi:	sta curdrv
			; create drive icon
			ldx #SIZEX
			ldy #SIZEY
			jsr frm_create
			sta curfrm
			ldx curposx
			ldy curposy
			jsr frm_setpos
			ldy #FFLG_PERM
			jsr frm_setflags
			jsr frm_getwin
			sta curwin
			jsr win_realize
			lda #WSTYLE_TXLEFT|WSTYLE_BCKGND|WSTYLE_TXTOP
			jsr win_setstyle
			ldy curdrv 
			lda drvhi-8, y
			tax
			lda drvlo-8, y
			jsr win_settext
			lda #WTYPE_BUTTON
			jsr win_settype
			lda curdrv
			jsr win_setuser
			lda #<ex_drive_button
			ldx #>ex_drive_button
			jsr win_setexec

			; draw window (icon)			
			lda curwin
			jsr win_draw
			lda curwin
			jsr win_show			; to screen

			; advance cur pos
			clc
			lda curposx
			adc #ADVX
			sta curposx
			
			rts

;
;	Icon button exec function
;

ex_drive_button:
			jsr btncheck
			jsr win_getuser
			tay
			and #3
			tax
			lda drvactive, x
			beq @showdrive
			jmp frm_activate
@showdrive:	tya
			jmp opendrive
			rts

;
;	Init drive vectors
;	INPUT:
;		curdrv .. drive number
;

initdrive:	lda curdrv
			and #3
			tax
			lda curfrm
			sta drvactive, x
			lda curbox
			sta drvlistbox, x
			lda listptr
			sta dirlistlo, x
			lda listptr+1
			sta dirlisthi, x
			lda listsize
			sta dirlistsz, x
			lda listlen
			sta dirlistlen, x
			rts

;
;	Select drive vectors
;	INPUT:
;		A .. drive number
;

seldrive:	cmp curdrv
			beq @done
			sta curdrv
			and #3
			tax
			lda drvactive, x
			sta curfrm
			lda drvlistbox, x
			sta curbox
			lda dirlistlo, x
			sta listptr
			lda dirlisthi, x
			sta listptr+1
			lda dirlistsz, x
			sta listsize
			lda dirlistlen, x
			sta listlen
			lda curfrm
			jsr frm_getwin
			sta curwin			
@done:		rts

;
;	Release drive data
;	INPUT:
;		A .. drive number
;

reldrive:	and #3
			sta curdrv
			tay
			lda dirlisthi, y
			tax
			lda dirlistlo, y
			jsr mfree
			lda curdrv
			tax
			lda #0
			sta curdrv
			sta drvactive, x
			sta drvlistbox, x
			sta dirlistlo, x
			sta dirlisthi, x
			sta dirlistsz, x
			sta dirlistlen, x
			rts

;
;	Inits title text
;	INPUT:
;		curdrv .. current drive no.
;	OUTPUT:
; 		A/X .. ptr to title text

inittitle:	jsr gettitle
			tay				; dec. ptr
			bne @nodex
			dex
@nodex:		dey
			tya
			jsr ssetbuf
			jsr sclear
			lda curdrv
			ldx #0
			jsr sputuint
			lda #':'
			jsr saddch
			; fall through

;
; 	Gets title text pointer for drive
;	INPUT:
;		curdrv .. current drive no.
;	OUTPUT:
; 		A/X .. ptr to title text
;

gettitle:	lda curdrv
			and #3
			tay
			lda txtdrvhi, y
			tax
			lda txtdrvlo, y
			rts

;
;	Updates title from first dir entry
;	 

fetchtitle:	jsr inittitle		; prepare title string
			lda #0				; get entry[0]
			jsr prepline
			ldx dreg+1			; copy file name
			lda dreg			
			clc
			adc #DirEntry::name
			bcc @noinx
			inx
@noinx:		jsr saddstr
			ldy #DirEntry::name	; set filename to "<-"
			ldx #0
@nxtname:	lda upname, x 
			sta (dreg), y
			iny
			inx
			cpx #2
			bcc @nxtname
			ldy #DirEntry::type	; set filetype to "DIR"
			ldx #0
@nxttype:	lda uptype, x 
			sta (dreg), y
			iny
			inx
			cpx #4
			bcc @nxttype
			jmp sstr2scr

	.segment "RODATA"
	
upname:		.byte 1, 95 ; '<-'
uptype:		.byte 3, "dir"
	
	.segment "CODE"

;
;	Open drive menu (A .. drive no.)
;

	WIN_SIZE_X = 144
	WIN_SIZE_Y = 112
	BORDER_OX = 4
	BORDER_OY = 4
	BUTTON_DX = 6*4
	BUTTON_DY = 12

opendrive:	sta curdrv
			; create frame
			ldx	#WIN_SIZE_X
			ldy #WIN_SIZE_Y
			jsr frm_create
			sta curfrm
			jsr frm_center
			; init main window
			jsr frm_getwin
			sta curwin
			jsr win_realize
			lda #WSTYLE_BCKGND|WSTYLE_HASTITLE|WSTYLE_BORDER
			jsr win_setstyle
			lda #2			; 4px font
			jsr win_setfont
			jsr inittitle
			jsr win_settext
			lda curdrv
			jsr win_setuser
			lda #<ex_drv_menu
			ldx #>ex_drv_menu
			jsr win_setexec
			lda curwin
			jsr addclsbtn
			
			; init listbox
			lda curwin
			ldx #<lbcreatest
			ldy #>lbcreatest
			jsr lb_create
			sta curbox
			
			; init buttons

			; "open"
			lda curwin
			jsr win_create
			lda #WSTYLE_BORDER
			jsr win_setstyle
			ldx #BORDER_OX
			ldy #WIN_SIZE_Y-BORDER_OY-BUTTON_DY
			jsr win_setpos
			ldx #BUTTON_DX
			ldy #BUTTON_DY
			jsr win_setdim
			lda #<tx_open
			ldx #>tx_open
			jsr win_settext
			lda #WTYPE_BUTTON
			jsr win_settype
;			lda #1			; lower case system font
;			jsr win_setfont
			lda #<ex_load
			ldx #>ex_load
			jsr win_setexec
			lda curdrv
			jsr win_setuser

			; "command"
			lda curwin
			jsr win_create
			lda #WSTYLE_BORDER
			jsr win_setstyle
			ldx #WIN_SIZE_X-BORDER_OX-BUTTON_DX
			ldy #WIN_SIZE_Y-BORDER_OY-BUTTON_DY
			jsr win_setpos
			ldx #BUTTON_DX
			ldy #BUTTON_DY
			jsr win_setdim
			lda #<tx_cmd
			ldx #>tx_cmd
			jsr win_settext
			lda #WTYPE_BUTTON
			jsr win_settype
;			lda #1			; lower case system font
;			jsr win_setfont
			lda #<ex_cmd
			ldx #>ex_cmd
			jsr win_setexec
			lda curdrv
			jsr win_setuser
			
			; draw window			
			lda curwin
			jsr win_draw
			lda curwin
			jsr win_show			; to screen
			
			jsr alloclist
			; fall through

;
;	Load directory from drive
;	INPUT:
;		curdrv ... drive number
;		curwin ... drive window
;		curbox ... listbox index
;

loaddir:	jsr cur_begwait
			jsr show_loading
@reread:	lda curdrv
			sta filespec		
			lda #<filespec
			ldx #>filespec
			jsr open
			bcs @openfail
			sta fileno
			ldy #5				; ignore first 4 bytes (start + link)
@readloop:	sty dmtmp
@readon:	jsr @readbyte
			dec dmtmp
			bne @readon
			sta fsize			; get file size
			jsr @readbyte
			sta fsize+1
@srchquote:	jsr @readbyte		; find "
			cmp #34
			bne @srchquote
			lda #<fname			; read name
			ldx #>fname
			jsr ssetbuf
			jsr sclear
@nameloop:	jsr @readbyte
			cmp #34
			beq @nameok
			jsr saddch
			jmp @nameloop
@nameok:	lda #<ftype			; read type
			ldx #>ftype
			jsr ssetbuf
			jsr sclear
@skpspc:	jsr @readbyte		; skip spaces
			cmp #32
			beq @skpspc
@typeloop:	jsr saddch
			jsr @readbyte
			cmp #0				; find zero
			beq @typeok
			jmp @typeloop
@typeok:	jsr @addentry
			jsr wait_yield 
			ldy #3				; next entry (ignore first 2 bytes)
			jmp @readloop
@readfail:	lda fileno			; close file
			jsr close
			lda curbox			; set listbox lines
			ldx listlen
			cpx fcnt
			beq @setlb
			bcc @realloc
@setlb:		jsr lb_setcnt
			jsr fetchtitle
@openfail:	jsr hide_loading	; restore window
			jsr cur_endwait
			jsr move_event
			jsr chkdstatus		; check drive status
@rdok:		rts			

@outmem:	lda #<txoutmem
			ldx #>txoutmem
			ldy #MSG_INFO
			jsr message
			lda curbox			; set listbox lines
			ldx listlen
			jmp @setlb

@realloc:	lda #.sizeof(DirEntry)
			ldx fcnt
			jsr bmul
			jsr malloc
			sta ptrlo
			stx ptrhi
			ora ptrhi
			beq @outmem
			lda listptr
			ldx listptr+1
			jsr mfree
			lda ptrlo
			sta listptr
			lda ptrhi
			sta listptr+1
			lda fcnt
			jsr initmem
			jmp @reread

@readbyte:	lda fileno
			jsr getc
			bcs @fail
			jsr fstatus
			cpx #0
			bne @fail
			rts
@fail:		pla				; pop return adress
			pla
			jmp @readfail

@addentry:	lda listlen				; check list length
			cmp listsize
			bcs @skipentry
			jsr prepline
			ldy #DirEntry::size		; store file size
			lda fsize
			sta (dreg), y
			iny
			lda fsize+1
			sta (dreg), y
			ldy #DirEntry::type		; copy file type
			ldx #0
@cptloop:	lda ftype+1, x
			sta (dreg), y
			iny
			inx
			cpx #MAX_TYPE_LEN+1
			bne @cptloop
			ldy #DirEntry::name		; copy file name
			ldx #0
@cpnloop:	lda fname+1, x
			sta (dreg), y
			iny
			inx
			cpx #MAX_NAME_LEN+1
			bne @cpnloop
			; check for D64
			lda fname+1
			cmp #5			; at least "x.d64" ?
			bcc @dnchk64
			sec
			sbc #4
			tax
			lda fname+2, x	; check for '.'
			cmp #'.'
			bne @dnchk64
			lda fname+3, x	; check for 'D'
			and #$5F
			cmp #$44
			bne @dnchk64
			; copy extension to type
			ldy #DirEntry::type		; copy file type
			lda #3
			sta (dreg), y
			iny
@cptlp2:	lda fname+3, x
			sta (dreg), y
			iny
			inx
			cpy #DirEntry::type+MAX_TYPE_LEN+1
			bne @cptlp2
@dnchk64:	inc listlen				; count entry
@skipentry:	inc fcnt
			rts

;
;	Reload directory
;

reloaddir:	lda #0
			sta listlen
			sta fcnt
			tax
			lda curbox
			jsr lb_setcnt
			jmp loaddir

;
;	Allocate initial list of dir entries
;

alloclist:	lda #<(INIT_LIST_SIZE*.sizeof(DirEntry))
			ldx #>(INIT_LIST_SIZE*.sizeof(DirEntry))
			jsr malloc
			sta listptr
			stx listptr+1
			ora listptr+1		; check for null ptr
			bne @memok
			pla					; "out of memory"
			pla
			jmp show_outmem 	
@memok:		lda #INIT_LIST_SIZE
initmem:	sta listsize
			lda #0
			sta listlen
			sta fcnt
			jmp initdrive

;
; Calc entry offset & setup dreg
; INPUT:
;		A ... entry index
; OUTPUT:
;		dreg .. entry ptr
;
prepline:	tax						; calc entry offset
			lda #.sizeof(DirEntry)
			jsr bmul
			clc
			adc listptr				; add base address
			sta dreg
			txa
			adc listptr+1
			sta dreg+1
			rts

;
; Prepare list pointer for active listbox
; INPUT:
; 		active listbox
; OUTPUT:
;		listptr, etc. set to assigned drive
; NOTE:
;		A unchanged
;

preplist:	pha
			jsr lb_getuser
			jsr seldrive
			pla
			rts

	.segment "DATA"

filespec:	.byte 8, 0, 1, "$"
fileno:		.byte 0
waitwin:	.byte 0
xpos:		.byte 0
ypos:		.byte 0
dmtmp:		.byte 0
fsize:		.word 0
fcnt:		.byte 0
fname:		.byte MAX_NAME_LEN, 0
			.res MAX_NAME_LEN
ftype:		.byte MAX_TYPE_LEN, 0
			.res MAX_TYPE_LEN
listptr:	.word 0
listsize:	.byte 0
listlen:	.byte 0
			
	.segment "RODATA"
	
loadtxt:	.byte 10, $4C, $0F, $01, $04, $09, $0E, $07, $2E, $2E, $2E
outmemtxt:	.byte 13, $4F, $15, $14, $20, $0F, $06, $20, $0D, $05, $0D, $0F, $12, $19

	.segment "DATA"
	
wtxtptr:	.word 0
	
	.segment "CODE"

show_outmem:
			lda #<outmemtxt
			ldx #>outmemtxt
			jmp show_wait
;
;	Display a text while loading from drive
;	INPUT:
;		curwin ... drive window
;	OUTPUT:
;		waitwin ... text window
;

show_loading:
			lda #<loadtxt
			ldx #>loadtxt
show_wait:	sta wtxtptr
			stx wtxtptr+1
			lda curwin
			jsr win_create
			sta waitwin
			lda #WSTYLE_BORDER|WSTYLE_BCKGND
			jsr win_setstyle
			lda #1	; system font
			jsr win_setfont
			lda wtxtptr
			ldx wtxtptr+1
			jsr win_settext
			
			lda #1
			jsr t_font
			lda wtxtptr
			ldx wtxtptr+1
			jsr t_getextent
			
			inx
			inx
			inx
			inx
			stx xpos
			iny
			iny
			iny
			iny
			sty ypos
			jsr win_setdim
			
			lda curwin
			jsr win_select
			jsr win_getdim
			txa
			sec
			sbc xpos
			lsr
			sta xpos
			tya
			sec
			sbc ypos
			lsr
			sta ypos
			lda waitwin
			jsr win_select
			ldx xpos
			ldy ypos
			jsr win_setpos
			
			lda waitwin
			jsr win_draw
			
			rts

;
;	Hide the info text again
;	INPUT:
;		curwin ... drive window
;		waitwin ... text window
;

hide_loading:
			lda waitwin
			jsr win_destroy
			rts

;
;	Reads status from current drive and shows errors in a message box
;	INPUT:
;		curdrv ... drive number (8..11)
;

chkdstatus:	lda curdrv
			sta cmdstatus
			lda #80
			jsr setrdbuf
			lda #<cmdstatus
			ldx #>cmdstatus
chkdstat2:	jsr dread
			jsr sgetlen
			beq @notprsnt
			lda scratchbuf1+2
			cmp #$30		; '0' (OK)
			beq @isok
			ldy #MSG_ERROR
			lda #<(scratchbuf1+1)
			ldx #>(scratchbuf1+1)
			jmp message
@isok:		rts

@notprsnt:	lda #<notprmsg
			ldx #>notprmsg
			ldy #MSG_ERROR
			jmp message

;
;	setup inbuf in scratchbuf1
;	INPUT:
;		A ... buf size
;	OUTPUT:
;		active string buffer
;
setrdbuf:	sta scratchbuf1
			lda #0
			sta scratchbuf1+1
			lda #<scratchbuf1
			ldx #>scratchbuf1
			jmp ssetbuf

	.segment "RODATA"
	
notprmsg:	.byte 18, "Drive not present."

	.segment "DATA"

cmdstatus:	.byte 8, 15, 0

	.segment "CODE"

;
;	Event handler for drive menu window
;

ex_drv_menu:
			ldy #Event::type
			lda (reg2), y
			cmp #EVT_WIN_DESTROY
			beq @close
			jmp ex_window
@close:		jsr win_getuser
			jmp reldrive

;
;	Gets item text for list box
;	INPUT:
;		X ... column
;		Y ... line
;	OUTPUT
;		A/X ... ptr to text
;

get_text1:	lda #DirEntry::type
			.byte $2C ; BIT ABS
get_text3:	lda #DirEntry::name
			pha	
			tya
			jsr preplist
			jsr prepline
			pla
			tay
			lda (dreg), y
			sta fname+1
			ldx #0
@tcploop:	iny
			inx
			lda (dreg), y
			jsr pet2scr
			sta fname+1, x
			cpx fname+1
			bne @tcploop
			lda #<(fname+1)
			ldx #>(fname+1)
			rts

get_text2:  tya
			jsr preplist
			jsr prepline		; locate entry
			lda #<fname			; prepare buf
			ldx #>fname
			jsr ssetbuf
			jsr sclear
			jsr get_blks
			lda #<(fname+1)
			ldx #>(fname+1)
			rts

;
;	Get blocks to current string
;

get_blks:	ldy #DirEntry::size+1
			lda (dreg), y		; get size
			tax
			dey
			lda (dreg), y
			jsr sputuint
			rts

;
;	Load button exec function
;

	MAX_CMD_LEN = MAX_NAME_LEN + 4

ex_load:	jsr btncheck
			jsr win_getuser		; locate entry info
			jsr seldrive
			lda curbox
			jsr lb_getpos
			jsr prepline
			ldy #DirEntry::type+1
			lda (dreg), y
			and #$7F
			cmp #$44			; is 'D'ir ?
			bne @chk_prg
			; change directory
			jsr prepcmd
			lda #<cdcmd
			ldx #>cdcmd
			jsr saddstr
			jsr setfname
			lda #15				; command channel
			sta cmdspec+1
			lda #<cmdspec
			ldx #>cmdspec
			jsr open
			jsr close
			jmp reloaddir
@chk_prg:	cmp #$50			; is 'P'rg?
			bne @done_exload
			jmp chkfile
@done_exload:
			rts

;
;	Check file type by reading header bytes
;	INPUT:
;		(dreg)	... dir entry
;

chkfile:	; read start address
			jsr prepcmd
			jsr setfname
			lda #0				; read channel
			sta cmdspec+1
			lda #<cmdspec
			ldx #>cmdspec
			jsr open
			sta fileno
			jsr getc
			bcs @rdfail
			sta staddr
			lda fileno
			jsr getc
			bcs @rdfail
			sta staddr+1
			lda fileno
			jsr close
			; setup file info data
			lda #<fid_name	; setup filename
			ldx #>fid_name
			jsr ssetbuf
			jsr sclear
			jsr setfname
			lda #<fid_title	; setup window title
			ldx #>fid_title
			jsr ssetbuf
			jsr sclear
			jsr setfname
			jsr sstr2scr
			lda #<fid_addr	; setup start address
			ldx #>fid_addr
			jsr ssetbuf
			jsr sclear
			lda staddr+1
			jsr sputhexb
			lda staddr
			jsr sputhexb
			lda #<fid_blks	; setup blocks
			ldx #>fid_blks
			jsr ssetbuf
			jsr sclear
			jsr get_blks
			jmp openfid

@rdfail:	lda fileno
			jsr close			
			jmp chkdstatus

;
;	 Prepare dir command buf. 
;
prepcmd:	lda curdrv
			sta cmdspec
			lda #MAX_CMD_LEN
			sta cmdspec+1
			lda #<(cmdspec+1)
			ldx #>(cmdspec+1)
			jsr ssetbuf
			jsr sclear
			rts
;
;	Get filename ptr in A/X
;	INPUT:
;		(dreg) .. dir entry
;	OUTPUT:
;		A/X .. ptr to file name in dir entry 
;
setfname:	ldx dreg+1
			lda dreg
			clc
			adc #DirEntry::name
			bcc @noinx
			inx
@noinx:		jmp saddstr

;
;	"command" button exec function
;

	MAX_INPUT_LEN = 2*MAX_NAME_LEN + 3
	CMD_HDIST = 2
	CMD_VDIST = 5
	CMD_BUTTON_WIDTH = 12
	CMD_CONTROL_HEIGHT = 12
	CMD_TITLE_HEIGHT = 10
	CMD_INPUT_WIDTH = MAX_INPUT_LEN * 4

ex_cmd:		jsr btncheck
			jsr win_getuser		; locate entry info
			sta drv_cmd
			jsr seldrive
			
			; prepare command buffer
			ldx #MAX_INPUT_LEN
			lda #32
			stx str_input
			stx cmd_input
@fill_n:	sta cmd_input, x
			dex
			bne @fill_n 

			; open command window
			lda h_cmd
			beq @skipclose
			jsr frm_destroy
			
@skipclose:	ldx #3*CMD_HDIST+CMD_INPUT_WIDTH+CMD_BUTTON_WIDTH
			ldy #CMD_TITLE_HEIGHT+2*CMD_VDIST+CMD_CONTROL_HEIGHT
			jsr frm_create
			sta h_cmd
			jsr frm_center
			jsr frm_getwin
			sta w_cmd
			jsr win_realize

			lda #WSTYLE_BCKGND|WSTYLE_HASTITLE|WSTYLE_BORDER
			jsr win_setstyle
			lda #2			; 4px font
			jsr win_setfont
			lda #<cmd_title
			ldx #>cmd_title
			jsr win_settext
			lda #<ex_cmdwin
			ldx #>ex_cmdwin
			jsr win_setexec
			lda curdrv
			jsr win_setuser
			lda w_cmd
			jsr addclsbtn

			; command input field
			lda w_cmd
			jsr win_create
			pha
			lda #WSTYLE_TXLEFT|WSTYLE_BCKGND
			jsr win_setstyle
			jsr win_getstate
			eor #EDIT_HAS_FOCUS
			jsr win_setstate
			ldx #CMD_HDIST
			ldy #CMD_TITLE_HEIGHT+CMD_VDIST
			jsr win_setpos
			ldx #CMD_INPUT_WIDTH
			ldy #CMD_CONTROL_HEIGHT
			jsr win_setdim
			lda #<cmd_input
			ldx #>cmd_input
			jsr win_settext
			lda #WTYPE_EDIT
			jsr win_settype
			lda w_cmd
			jsr win_select
			pla
			jsr win_setfocus
			
			; command send button
			lda w_cmd
			jsr win_create
			lda #WSTYLE_BORDER
			jsr win_setstyle
			ldx #2*CMD_HDIST+CMD_INPUT_WIDTH
			ldy #CMD_TITLE_HEIGHT+CMD_VDIST
			jsr win_setpos
			ldx #CMD_BUTTON_WIDTH
			ldy #CMD_CONTROL_HEIGHT
			jsr win_setdim
			lda #<cmd_button
			ldx #>cmd_button
			jsr win_settext
			lda #WTYPE_BUTTON
			jsr win_settype
			lda #<ex_send_cmd
			ldx #>ex_send_cmd
			jsr win_setexec

			; draw window			
			lda w_cmd
			jsr win_draw
			lda w_cmd
			jmp win_show			; to screen

;
;	Event handler for command window send button
;

ex_send_cmd:
			jsr btncheck
			lda h_cmd
			jsr frm_destroy
			lda #<str_input
			ldx #>str_input
			jsr ssetbuf
			jsr strim
			jsr sscr2str
			lda #15			; cmd channel
			sta str_input
			lda #80
			jsr setrdbuf
			lda #<drv_cmd
			ldx #>drv_cmd
			jsr chkdstat2
			jmp reloaddir

;
;	Event handler for command window
;

ex_cmdwin:	ldy #Event::type
			lda (reg2), y
			cmp #EVT_WIN_DESTROY
			bne done_excw
			lda #0
			sta h_cmd
done_excw:	rts


	.segment "DATA"
	
h_cmd:		.byte 0
w_cmd:		.byte 0
; string buffer for a disk command
drv_cmd:	.byte 0
str_input:	.byte 35
cmd_input:	.byte 35 ; MAX_INPUT_LEN
			.repeat 35 ; MAX_INPUT_LEN
				.byte 32
			.endrep

	.segment "RODATA"
	
cmd_title:	.byte 13 ; "Send command:"
			.byte $53, $05, $0E, $04, $20
			.byte $03, $0F, $0D, $0D, $01, $0E, $04, $3A
			
cmd_button: .byte 1, 0 ; "@"	
	
; List of known start addresses
; Don't change first three entries!
rbchkhi:		.byte $10, $04, $12, $10
rbchklo:		.byte $01, $01, $01, $F1
rbchkidx:		.byte 0, 1, 2 , 2

	RB_CHK_LEN = 4
	RB_CHK_DEF = 2	; Default: 8K+

	.segment "CODE"

	FID_SIZE_X = 96
	FID_SIZE_Y = 64

;
;	Open file info window
;

openfid:	jsr closefid
			; create frame
			ldx	#FID_SIZE_X
			ldy #FID_SIZE_Y
			jsr frm_create
			sta fid_frm
			jsr frm_center
			; init main window
			jsr frm_getwin
			sta fid_win
			jsr win_realize
			lda #WSTYLE_BCKGND|WSTYLE_HASTITLE|WSTYLE_BORDER
			jsr win_setstyle
			lda #2			; 4px font
			jsr win_setfont
			lda #<(fid_title+1)
			ldx #>(fid_title+1)
			jsr win_settext
			lda #<ex_fidwin
			ldx #>ex_fidwin
			jsr win_setexec
			lda curdrv
			jsr win_setuser
			lda fid_win
			jsr addclsbtn
			; create label "Start"
			lda fid_win
			jsr win_create
			lda #WSTYLE_TXLEFT
			jsr win_setstyle
			ldx #4
			ldy #14
			jsr win_setpos
			ldx #20
			ldy #8
			jsr win_setdim
			lda #<txfid_addr
			ldx #>txfid_addr
			jsr win_settext
			; create label for adress
			lda fid_win
			jsr win_create
			lda #WSTYLE_TXLEFT
			jsr win_setstyle
			ldx #28
			ldy #14
			jsr win_setpos
			ldx #16
			ldy #8
			jsr win_setdim
			lda #<(fid_addr+1)
			ldx #>(fid_addr+1)
			jsr win_settext
			; create label "Bl."
			lda fid_win
			jsr win_create
			lda #WSTYLE_TXLEFT
			jsr win_setstyle
			ldx #4
			ldy #26
			jsr win_setpos
			ldx #12
			ldy #8
			jsr win_setdim
			lda #<txfid_blks
			ldx #>txfid_blks
			jsr win_settext
			; create label for # of blocks
			lda fid_win
			jsr win_create
			lda #WSTYLE_TXRIGHT
			jsr win_setstyle
			ldx #24
			ldy #26
			jsr win_setpos
			ldx #20
			ldy #8
			jsr win_setdim
			lda #<(fid_blks+1)
			ldx #>(fid_blks+1)
			jsr win_settext
			
			; create memory radios
			ldx #0
			stx rbidx
			
@chklp:		lda staddr+1
			cmp rbchkhi, x
			bne @next
			lda staddr
			cmp rbchklo, x
			bne @next
			lda rbchkidx, x
			bpl @finmem
@next:
			cpx #RB_CHK_LEN-1
			beq @notfound
			inx
			bne @chklp
			
@notfound:	lda #RB_CHK_DEF
			
@finmem:	sta rbact

@crtrbbtn:	lda fid_win			; unexp
			jsr win_create
			ldy rbidx
			sta rbbtn, y			
			ldx #56
			lda rbposy, y
			tay
			jsr win_setpos
			ldx #8
			ldy #8
			jsr win_setdim
			lda rbidx
			cmp rbact
			beq @sel
@unsel:		lda #<tx_unsel
			ldx #>tx_unsel
			jmp @settx
@sel:		lda #<tx_sel
			ldx #>tx_sel
@settx:		jsr win_settext
			lda #WSTYLE_BCKGND
			jsr win_setstyle
			lda #WTYPE_BUTTON
			jsr win_settype
			lda rbidx
			jsr win_setuser
			lda #<ex_rbbtn
			ldx #>ex_rbbtn
			jsr win_setexec
			
			lda fid_win
			jsr win_create
			lda #WSTYLE_TXLEFT
			jsr win_setstyle
			ldx #68
			ldy rbidx
			lda rbposy, y
			tay
			jsr win_setpos
			ldx #32
			ldy #8
			jsr win_setdim
			ldy rbidx
			lda rblo, y
			ldx rbhi, y
			jsr win_settext
			
			inc rbidx
			lda rbidx
			cmp #3
			bcc @crtrbbtn
			
			lda fid_blks+1		; launch only for bl. < 100
			cmp #3
			bcs @nolaunch			
			; create launch button
			lda fid_win
			jsr win_create
			lda #WSTYLE_BORDER
			jsr win_setstyle
			ldx #(FID_SIZE_X - 7*4)/2
			ldy #48
			jsr win_setpos
			ldx #7*4
			ldy #12
			jsr win_setdim
			lda #<txfid_btn
			ldx #>txfid_btn
			jsr win_settext
			lda #WTYPE_BUTTON
			jsr win_settype
			lda #<ex_lnchbtn
			ldx #>ex_lnchbtn
			jsr win_setexec
@nolaunch:			
			; draw window			
			lda fid_win
			jsr win_draw
			lda fid_win
			jsr win_show			; to screen
			
			rts

;
;	Event handler for file info window
;

ex_fidwin:	ldy #Event::type
			lda (reg2), y
			cmp #EVT_WIN_DESTROY
			bne done_exl
			lda #0
			sta fid_frm
done_exl:	rts

;
;	Event handler for launch button
;

ex_lnchbtn:	jsr btncheck
			ldx rbact		; setup RAM
			lda rbchkhi, x
			sta $282		; start of memory
			cpx #2
			bcs @fullram
			lda #$1e
			sta $288		; screen mem page
			sta $284		; end of memory
@fullram:	lda #<fid_name	; setup filename
			ldx #>fid_name
			jsr ssetbuf
			lda #$00
			ldx #$01
			jsr scopyto
			lda curdrv		; setup drive no
			sta $FF
			jmp $033C		; jump to loader
closefid:	lda fid_frm
			beq done_exl
			jmp frm_destroy

;
;	Event handler for radio button
;

ex_rbbtn:	jsr btncheck
			jsr win_getuser
			cmp rbact
			beq @done_rbb
			sta rbidx
			ldx rbact		; unselect old btn
			lda rbbtn, x
			jsr win_select
			lda #<tx_unsel
			ldx #>tx_unsel
			jsr win_settext
			ldx rbact
			lda rbbtn, x
			jsr win_draw
			ldx rbidx		; select new btn
			stx rbact
			lda rbbtn, x
			jsr win_select
			lda #<tx_sel
			ldx #>tx_sel
			jsr win_settext
			ldx rbact
			lda rbbtn, x
			jsr win_draw

@done_rbb:	rts

	.segment "RODATA"
	
cdcmd:		.byte 3, $43, $44, ':'

	.segment "DATA"

cmdspec:	.byte 8, 0, 0
			.res MAX_CMD_LEN

; program start address
staddr:		.word 0

; Radio button data
rbact:		.byte 0
rbidx:		.byte 0
rbbtn:		.res 3

; file info data
fid_name:	.byte MAX_NAME_LEN, 0
			.res MAX_NAME_LEN
fid_title:	.byte MAX_NAME_LEN, 0
			.res MAX_NAME_LEN
fid_addr:	.byte 4, 0
			.res 4
fid_blks:	.byte 5, 0
			.res 5
fid_frm:	.byte 0
fid_win:	.byte 0

	.segment "RODATA"
	
; File info text
txfid_addr:	.byte 5, $53, $14, $01, $12, $14 ; "Start"
txfid_blks:	.byte 3, $42, $0C, $2E ; "Bl." 
txfid_btn:	.byte 6, $4C, $01, $15, $0E, $03, $08 ; "Launch"
txfid_unex:	.byte 6, $55, $0E, $05, $18, $10, $2E ; "Unexp."
txfid_3k:	.byte 2, $33, $4B ; "3K"
txfid_8k:	.byte 3, $38, $4B, $2B ; "8K+"

; Radio button lists
rblo:		.byte <txfid_unex, <txfid_3k, <txfid_8k
rbhi:		.byte >txfid_unex, >txfid_3k, >txfid_8k
rbposy:		.byte 14, 24, 34

; Radio button bitmaps
tx_unsel:	.byte $FF
			.word bm_unsel
tx_sel:		.byte $FF
			.word bm_sel

bm_unsel:	.byte 8, 8
			.word bmpunsel
bmpunsel:	.byte $3C, $42, $81, $81, $81, $81, $42, $3C
bm_sel:		.byte 8, 8
			.word bmpsel
bmpsel:		.byte $3C, $42, $99, $BD, $BD, $99, $42, $3C

; Drive directory titles
txtdrvlo:	.byte <txtdrv8, <txtdrv9, <txtdrv10, <txtdrv11
txtdrvhi:	.byte >txtdrv8, >txtdrv9, >txtdrv10, >txtdrv11

; LbCreateStruct for directory listbox
lbcreatest:	.byte BORDER_OX ; left
			.byte BORDER_OY+WIN_TITLE_HEIGHT ; top
			.byte WIN_SIZE_X-2*BORDER_OX ; width
			.byte WIN_SIZE_Y-3*BORDER_OY-BUTTON_DY-WIN_TITLE_HEIGHT ; height
			.byte 2 ; font
			.byte 3 ; columns
; column 1
			.byte 4*4	; width
			.word col1title ; title
			.byte WSTYLE_TXLEFT ; txpos_title
			.byte WSTYLE_TXLEFT ; txpos_item
			.word get_text1
; column 2
			.byte 6*4	; width
			.word col2title ; title
			.byte WSTYLE_TXLEFT ; txpos_title
			.byte WSTYLE_TXRIGHT ; txpos_item
			.word get_text2
; column 3
			.byte 16*4	; width
			.word col3title ; title
			.byte WSTYLE_TXLEFT ; txpos_title
			.byte WSTYLE_TXLEFT ; txpos_item
			.word get_text3

col1title:	.byte 2, $54, $2E ; "T."
col2title:	.byte 3, $42, $0C, $2E ; "Bl."
col3title:	.byte 4, $4E, $01, $0D, $05 ; "Name"

	.segment "DATA"

	MAX_TITLE_LENGTH = 20

strdrv8:	.byte MAX_TITLE_LENGTH
txtdrv8:	.byte 0
			.res MAX_TITLE_LENGTH
strdrv9:	.byte MAX_TITLE_LENGTH
txtdrv9:	.byte 0
			.res MAX_TITLE_LENGTH
strdrv10:	.byte MAX_TITLE_LENGTH
txtdrv10: 	.byte 0
			.res MAX_TITLE_LENGTH
strdrv11:	.byte MAX_TITLE_LENGTH
txtdrv11:	.byte 0
			.res MAX_TITLE_LENGTH
